﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Threading;
using Phone.Framework.CaliburnExtensions.Results;

namespace Phone.Framework.Threads
{
    public class Task:ITask
    {
        public Action Action { get; set; }

        

        public Action Complated { get; set; }

        #region ITask Members

        public virtual void Execute()
        {
            Action();
            //if (Complated != null)
            //    Complated();
        }

        #endregion
    }

    public interface ITask
    {
        void Execute();
    }

    public class TaskWithLoading : Task
    {
        public override void Execute()
        {
            UIThread.Invoke(() =>
            {
                ResultHelper.Execute(LoadingResult.Default());
            });

            Action();
            UIThread.Invoke(() =>
            {
                ResultHelper.Execute(LoadedResult.Default());
            });

            if (Complated != null)
                Complated();
        }
    }

    public static class ThreadManagerExtension
    {
        public static void TaskWithLoading(this ThreadManager tm, Action task)
        {
            tm.AddTask(new TaskWithLoading() { Action = task, Complated = null });
        }

        public static void TaskWithLoading(this ThreadManager tm, Action task, Action complated)
        {
            tm.AddTask(new TaskWithLoading() { Action = task, Complated = complated });
        }
    }

    public sealed class ThreadManager
    {

        private Queue<ITask> _queue = new Queue<ITask>();
        private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

        private Thread _thread;

        private ThreadManager()
        {
            _thread = new Thread(Running);
            _thread.IsBackground = true;
            _thread.Start();
        }
        private static readonly ThreadManager tm=new ThreadManager();
        private static readonly object padlock = new object();
        public static ThreadManager Instance
        {
            get
            {
                return tm;
            }
        }

        public static ThreadManager CreateInstance()
        {
            return new ThreadManager();
        }

        public void AddTask(Action task)
        {
            AddTask(task,null);
        }

        public void AddTask(Action task,Action complated)
        {
            AddTask(new Task() { Action = task, Complated = complated });
        }

        public void AddTask(ITask task)
        {
            lock (padlock)
            {
                _queue.Enqueue(task);
            }
        }

        private void Running()
        {
            while (true)
            {
                if (_queue.Count > 0)
                {
                    ITask task = _queue.Dequeue();
                    task.Execute();
                }
            }
        }
    }
}